/**
 * @method axios
 * @param {config<Objcet>} 必填，接口参数对象
 *        @property {config} 例：{url: '/api/login', method: 'GET', params: {username: 'xingjie'}}
 *        @property {url}  必填，接口路径
 *        @property {method}  请求方式
 *        @property {params}  请求参数——query
 *        @property {data}  请求参数——body
 *        @property {headers}  请求头——headers
 * @param {debounce<Boolean|Object> = false} 是否开启防抖
 *        @property {debounce=false} 例：true || { key: 'getUserInfo', millisec: 1500, time: 500}
 *        @property {millisec=1500}  取消防抖等待时间
 *        @property {time=500}  防抖延迟时间
 * @return axios请求的Promise函数
 */

import { hint } from '@/utils/tools'
import store from '@/store'
import { getToken } from '@/utils/auth'
import { HighAxios, hasOwn } from 'xj-tools'

const debounceConfig = { millisec: 1500, time: 500 }
const keys = {}

const errorCallback = (msg) => {
  hint({
    message: msg,
    type: 'error',
    duration: 5 * 1000
  })
}

const checkDebounce = (url) => {
  if (hasOwn(keys, url)) {
    if (keys[url] === true) {
      keys[url] = false
      setTimeout(() => {
        keys[url] = true
      }, debounceConfig.millisec)
    }
  }
}

const request = (config) => {
  if (getToken()) {
    config.headers['token'] = getToken()
  }

  if (config.method === 'post') {
    config.headers['Content-Type'] = 'application/json'
  }
  checkDebounce(config.url)

  return config
}

const response = (resp) => {
  const res = resp.data
  if (res.code === 10200) {
    return res.data || res
  } else if (res.code === 10401) {
    hint.error('登录已失效，请重新登录')
    store.dispatch('LogOut')
    return Promise.reject('登录已失效，请重新登录')
  } else {
    hint({
      message: res.msg,
      type: 'error',
      duration: 5 * 1000
    })
    return Promise.reject(res.msg || '操作失败')
  }
}

const responseError = (error) => {
  if (keys[error.config.url] === false) {
    keys[error.config.url] = true
  }
  hint({
    message: '连接超时',
    type: 'error',
    duration: 5 * 1000
  })
  return Promise.reject(error)
}

const params = {
  baseURL: process.env.VUE_APP_BASEURL,
  timeout: 60000,
  errorCallback,
  request,
  response,
  responseError
}

const highAxios = new HighAxios(params)

const axios = (config, debounce = false) => {
  if (hasOwn(keys, config.url) && keys[config.url] === false) {
    return Promise.reject('操作太频繁！')
  }

  if (debounce && typeof debounce === 'boolean') {
    keys[config.url] = true
  }
  if (debounce && Object.prototype.toString.call(debounce) === '[object Object]') {
    keys[config.url] = true
    debounceConfig.time = debounce.time || 500
    debounceConfig.millisec = config.timeout || 1500
  }
  return highAxios.server(config)
}

export default axios

